using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;

namespace IUPUI.StellarResults
{
	/// <summary>
	/// Represents a date time interval.
	/// </summary>
	[Serializable]
	[TypeConverter(typeof(ExpandableObjectConverter))]
	public class DateTimeInterval : ININ.Xml.Serialization.XmlSerializationBase,
		INotifyPropertyChanged
	{
		#region Private Properties
		private ININ.DateTimeUnit m_Unit =
			ININ.DateTimeUnit.Minutes;
		private double m_Value = 5;
		#endregion Private Properties

		#region Public Properties

		/// <summary>
		/// Gets or sets the unit.
		/// </summary>
		/// <value>The unit.</value>
		[Category("DateTimeInterval")]
		[Description("Gets or sets the unit.")]
		public ININ.DateTimeUnit Unit
		{
			get
			{
				return m_Unit;
			}
			set
			{
				m_Unit = value;
				OnPropertyChanged("DateTimeUnit");
			}
		}

		/// <summary>
		/// Gets or sets the value.
		/// </summary>
		/// <value>The value.</value>
		[Category("DateTimeInterval")]
		[Description("Gets or sets the value.")]
		public double Value
		{
			get
			{
				return m_Value;
			}
			set
			{
				m_Value = value;
				OnPropertyChanged("Value");
			}
		}
		#endregion Public Properties

		#region Constructors
		/// <summary>
		/// Initializes a new instance of the <see cref="DateTimeInterval"/> class.
		/// </summary>
		public DateTimeInterval()
		{
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="DateTimeInterval"/> class.
		/// </summary>
		/// <param name="value">The value.</param>
		/// <param name="dateTimeUnit">The date time unit.</param>
		public DateTimeInterval(
			double value,
			ININ.DateTimeUnit dateTimeUnit)
		{
			m_Unit = dateTimeUnit;
			m_Value = value;
		}
		#endregion Constructors

		#region Overrides
		/// <summary>
		/// Returns a <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.
		/// </summary>
		/// <returns>
		/// A <see cref="T:System.String"/> that represents the current <see cref="T:System.Object"/>.
		/// </returns>
		/// <filterPriority>2</filterPriority>
		public override string ToString()
		{
			return String.Format("{0} {1}",
				m_Value,
				m_Unit.ToString());
		}
		#endregion Overrides

		#region INotifyPropertyChanged Members
		/// <summary>
		/// Called when [property changed].
		/// </summary>
		/// <param name="propertyName">Name of the property.</param>
		private void OnPropertyChanged(
			string propertyName)
		{
			if (m_PropertyChanged != null)
			{
				m_PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
			}
		}

		private PropertyChangedEventHandler m_PropertyChanged;

		/// <summary>
		/// Occurs when [property changed].
		/// </summary>
		public event PropertyChangedEventHandler PropertyChanged
		{
			add
			{
				m_PropertyChanged += value;
			}
			remove
			{
				m_PropertyChanged -= value;
			}
		}
		#endregion INotifyPropertyChanged Members 

		#region IDisposable Members
		private bool m_IsDisposed = false;

		/// <summary>
		/// Gets a value indicating whether this instance is disposed.
		/// </summary>
		/// <value>
		/// 	<c>true</c> if this instance is disposed; otherwise, <c>false</c>.
		/// </value>
		[Browsable(false)]
		public bool IsDisposed
		{
			get
			{
				return m_IsDisposed;
			}
		}

		private event System.EventHandler m_Disposed;

		/// <summary>
		/// Occurs when this instance is disposed.
		/// </summary>
		public event System.EventHandler Disposed
		{
			add
			{
				m_Disposed += value;
			}
			remove
			{
				m_Disposed -= value;
			}
		}

		/// <summary>
		/// Releases unmanaged and - optionally - managed resources
		/// </summary>
		public void Dispose()
		{
			if (!m_IsDisposed)
			{
				this.Dispose(true);
				GC.SuppressFinalize(this);
			}
		}

		/// <summary>
		/// Releases unmanaged and - optionally - managed resources
		/// </summary>
		/// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
		protected virtual void Dispose(bool disposing)
		{
			try
			{
				if (disposing)
				{
					m_PropertyChanged = null;

					if (m_Disposed != null)
					{
						m_Disposed(this, EventArgs.Empty);
						m_Disposed = null;
					}
				}
			}
			finally
			{
				m_IsDisposed = true;
			}
		}
		#endregion IDisposable Members
	}
}
